package com.atguigu.gmall.payment.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.mq.mqconst.MqOrderConst;
import com.atguigu.gmall.mq.service.RabbitService;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.PaymentInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;

@Controller
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private AlipayClient alipayClient;

    /**
     * 支付宝异步回调
     *
     * @param paramsMap
     * @return
     * @throws AlipayApiException
     */
    @ResponseBody
    @PostMapping("/callback/notify")
    public String asyncCallback(@RequestParam Map<String, String> paramsMap) throws AlipayApiException {
        boolean sign = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        if (sign) {
            String tradeStatus = paramsMap.get("trade_status");
            if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)) {
                return "failure";
            }

            String outTradeNo = paramsMap.get("out_trade_no");
            PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOutTradeAndType(outTradeNo, PaymentType.ALIPAY.toString());
            paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
            paymentInfo.setTradeNo(paramsMap.get("trade_no"));
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setCallbackContent(JSONObject.toJSONString(paramsMap));
            paymentInfoService.updatePaymentInfoStatus(paymentInfo);

            //mq发消息 更改订单状态为已支付
            rabbitService.sendMessage(MqOrderConst.EXCHANGE_ORDER, MqOrderConst.ROUTING_KEY_ORDER, paymentInfo.getOrderId());


            return "success";
        } else {
            return "failure";
        }
    }

    /**
     * 支付宝同步回调
     *
     * @return
     */
    @RequestMapping("/callback/return")
    public String syncCallback() {
        return "redirect:" + AlipayConfig.return_order_url;
    }

    @ResponseBody
    @GetMapping("/submit/{outTradeNo}")
    public String showCodePage(@PathVariable("outTradeNo") String outTradeNo) throws AlipayApiException {
        OrderInfo orderInfo = orderFeignClient.getOrderInfoByOutTradeNo(outTradeNo).getData();
        if (orderInfo == null) {
            return "当前订单无法支付";
        }
        String orderStatus = orderInfo.getOrderStatus();
        if (!OrderStatus.UNPAID.toString().equals(orderStatus)) {
            return "当前订单无法支付";
        }

        String payType = PaymentType.ALIPAY.toString();
        PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOutTrade(outTradeNo, payType);
        if (paymentInfo == null) {
            paymentInfo = new PaymentInfo();
            paymentInfo.setOutTradeNo(outTradeNo);
            paymentInfo.setOrderId(orderInfo.getId());
            paymentInfo.setPaymentType(payType);
            paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
            paymentInfo.setSubject(orderInfo.getTradeBody());
            paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.toString());
            paymentInfo.setCreateTime(new Date());
            paymentInfoService.save(paymentInfo);
        }

        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(AlipayConfig.notify_payment_url);
        request.setReturnUrl(AlipayConfig.return_payment_url);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("out_trade_no", outTradeNo);
        jsonObject.put("total_amount", orderInfo.getTotalAmount());
        jsonObject.put("subject", orderInfo.getTradeBody());
        jsonObject.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(jsonObject.toString());
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
        if (response.isSuccess()) {
            return response.getBody();
        } else {
            return "失败";
        }
    }

    //查询交易结果
    @ResponseBody
    @GetMapping("/check/pay/status/remote/{outTradeNo}")
    public Result<Boolean> checkPayStatusRemote(@PathVariable("outTradeNo") String outTradeNo) {
        boolean checkPayStatus = paymentInfoService.checkPayStatusRemote(outTradeNo);
        return Result.ok(checkPayStatus);
    }

    //关闭支付宝交易订单
    @ResponseBody
    @GetMapping("/close/pay/remote/{outTradeNo}")
    public Result<Boolean> closePay(@PathVariable("outTradeNo") String outTradeNo) {
        boolean checkPayStatus = paymentInfoService.closePay(outTradeNo);
        return Result.ok(checkPayStatus);
    }

    //关闭paymentInfo订单
    @ResponseBody
    @GetMapping("/close/paymentInfo/status/remote/{outTradeNo}")
    public Result<Boolean> closePaymentInfo(@PathVariable("outTradeNo") String outTradeNo) {
        boolean checkPayStatus = paymentInfoService.closePaymentInfo(outTradeNo);
        return Result.ok(checkPayStatus);
    }

}
